<template>
    <view class="rain-container" v-if="visible">
        <view v-if="readyVisible" class="ready-time">
            <view class="top">一大波红包即将来袭</view>
            <view class="countdown">{{readyTime}}</view>
        </view>
        <view v-else>
            <view class='rain-bg' :class="{'rain-bg-hide':isGameOver}">
                <cax id="myCanvas" class="cax-class" :style="bg_img_style">
                    <slot></slot>
                    <block v-if="custom === false">
                        <view class='timeout-warpper'>
                            <view class="timeout">倒计时</view>
                            <view class="sec">
                                <view class="numOfTime">{{time}}</view>
                                <view class="miao">s</view>
                            </view>
                        </view>
                        <view class="rain-score">
                            <view>金币:{{showScore}}</view>
                            <view class='scoreChangeClass' :animation="animationData">{{showChangeScore>0 ?
                                "+":""}}{{showChangeScore}}
                            </view>
                        </view>
                    </block>
                </cax>
            </view>
            <view class='rain-bg rain-over' :class="{'rain-bg-hide':!isGameOver}">
                <view class="bg">
                    <view class='shadeView'>
                        <slot name="score-view"></slot>
                        <block v-if="custom === false">
                            <view class="shadeView-top">恭喜您获得</view>
                            <view class='shadeView_scoreView'>
                                <text>{{showScore}}</text>
                                <text>金币</text>
                            </view>
                            <view class='shadeView_gameOverBtn'>
                                <view class="explain">金币已存入您的账户中</view>
                                <view class="explain">可用于下单时抵扣商品金额</view>
                                <view class="btn" @tap="handleFinish">我知道了</view>
                                <view class="rule" @tap="handleCheckrule">查看规则></view>
                            </view>
                        </block>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    import cax from '@s/js_sdk/cax.js'


    let RDC = '/static/packet-rain/rdc.png';
    // #ifdef H5
    RDC = require('../../../../static/packet-rain/rdc.png');
    // #endif
    const DIANJI = '/static/packet-rain/dianji.mp3';

    const info = uni.getSystemInfoSync();
    const innerAudioContext = uni.createInnerAudioContext();
    let shapeArray = [];

    const OPTS = {
        // 红包发放模式:1:红包总金额有上限,2:红包金额无上限
        mode: {
            type: Number,
            value: 1
        },
        // 初始速度
        createSpeed: {
            type: Number,
            value: 400
        },
        // 游戏时间单位秒
        time: {
            type: Number,
            value: 15
        },
        // 倒计时单位秒
        readyTime: {
            type: Number,
            value: 5
        },
        // 金币、金额上限
        total: {
            type: Number,
            value: 100
        },
        // 红包个数
        number: {
            type: Number,
            value: 10
        },
        // 单个最小金额
        min: {
            type: Number,
            value: 0
        },
        // 单个最大金额
        max: {
            type: Number,
            value: 3
        },
        // 金额小数位
        decimal: {
            type: Number,
            value: 0
        },
        // 背景图片
        bg_img: {
            type: String,
            value: ""
        },
        // 红包图片
        rdc_img: {
            type: String,
            value: ""
        }
    }

    const DEFAULT = {
        score: 0, // 总分数
        showScore: 0,
        showChangeScore: 0,
        gameTimer: '', // 游戏Timer
        createPacketTimer: '', // 创建红包Timer
        packetMoveDownTimer: '', // 红包下落Timer
        readyRainTimer: null, // 准备时间Timer
        readyVisible: true, // 显示准备倒计时
        isGameOver: false,
        packetArr: [],

        animationData: false,

        // 属性
        mode: 1,
        createSpeed: 400,
        time: 15,
        readyTime: 5,
        total: 100,
        number: 10,
        min: 0,
        max: 3,
        decimal: 0,

        // 是否开始游戏
        visible: false,

        // 背景图片
        bg_img: "",
        // 红包图片
        rdc_img: ""

    };

    const TimeoutTimers = [];
    const IntervalTimers = [];


    export default {
        name: "tl-packet-rain",
        components: {},
        props: {
            options: {
                type: Object,
                default(d) {
                    return d || {}
                }
            },
            custom: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                ...DEFAULT,
                bg_img_style: ''
            }
        },
        watch: {
            options() {
                this.init()
            }
        },
        created() {
        },
        mounted() {
            // 初始化数据
            this.init();
        },
        destroyed() {
            this.clearTimer()
        },
        methods: {
            init() {
                const initVal = {...DEFAULT, ...this.options};
                console.log(initVal);
                this.$util.mapKeys(initVal, this, Object.keys(OPTS));
                this.setImages();
                this.clearTimer();
                this.$emit('init', this.createMethods())
            },

            setImages() {
                if (!this.$util.jude.isEmpty(this.bg_img)) {
                    if (typeof this.bg_img === "string") {
                        this.bg_img_style = this.$util.object2style({
                            backgroundImage: `url('${this.bg_img}')`
                        })
                    } else if (this.bg_img === false) {
                        this.bg_img_style = this.$util.object2style({
                            backgroundImage: `none`
                        })
                    }
                }

            },

            createMethods() {
                let vm = this;

                class PR {
                    constructor() {

                    }

                    start = vm.start.bind(vm);
                    clearTimer = vm.clearTimer.bind(vm)
                }

                return new PR()
            },

            clearTimer() {
                IntervalTimers.forEach(v => clearInterval(v));
                TimeoutTimers.forEach(v => clearTimeout(v));
            },

            // 倒计时开始
            start() {
                let that = this;
                if (that.visible) return;
                that.visible = true;
                that.readyRainTimer = setInterval(function () {
                    if (that.readyTime <= 0) {
                        // 清除准备倒计时
                        clearInterval(that.readyRainTimer);
                        that.readyVisible = false;
                        // 开始红包雨
                        that.play()
                    } else {
                        that.readyTime -= 1
                    }
                }, 1000);
                IntervalTimers.push(this.readyRainTimer);
            },
            delayMethod(t = 500) {
                return new Promise(resolve => {
                    TimeoutTimers.push(setTimeout(r => {
                        resolve()
                    }, t))
                })
            },
            // 游戏开始
            play() {
                this.$nextTick(function () {
                    // #ifdef H5
                    var bgStage = new cax.Stage(info.windowWidth, info.windowHeight, '#myCanvas');
                    // #endif
                    // #ifdef MP-WEIXIN
                    var bgStage = new cax.Stage(info.windowWidth, info.windowHeight, 'myCanvas', this);
                    // #endif
                    // 创建红包
                    this.createPacket(bgStage);
                    // 红包下落
                    this.packetMoveDown(bgStage);
                    //倒计时关闭
                    this.stopRain(bgStage);
                    this.audioOfClick()
                })
            },
            // 点击音频
            audioOfClick() {
                innerAudioContext.autoplay = false;
                innerAudioContext.src = DIANJI;
                innerAudioContext.onPlay(() => {
                })
                innerAudioContext.onError(res => {
                })
            },
            // 创建红包
            createPacket(bgStage) {
                const that = this;
                let indexNum = 0;
                let n = 0;
                const {total, number, max, min, time, mode, createSpeed} = this;
                // 红包总金额有上限,我上限必须设置createSpeed
                if (mode === 1) {
                    n = (time * 1000) / number;
                    // 产生一组随机金额
                    that.packetArr = this.randomRedPacketGenerator(number, total, min, max);
                } else {
                    n = createSpeed
                }
                // 每 n 毫秒创建一个，n为 this.createSpeed
                console.log(n, '毫秒创建一个红包');
                this.createPacketTimer = setInterval(function () {
                    const redCardName = 'redCard' + String(indexNum);
                    // 创建红包
                    that.createShape(bgStage, redCardName, indexNum);
                    indexNum++
                }, n);
                IntervalTimers.push(this.createPacketTimer);
            },
            //创建红包形状
            createShape(newStage, newName, index) {
                //创建随机位置
                let that = this;
                let ranNum = Math.random() * (info.windowWidth - 80);
                // 红包背景
                newName = new cax.Bitmap(RDC);
                // 旋转角度
                let angle = Math.random() * 90 - 45;
                newName.rotation = angle;
                // 随机大小缩放0.4~0.5
                newName.scaleX = newName.scaleY = (Math.random() * 10 + 40) / 100;
                // x轴随机位置
                newName.x = ranNum;
                // y轴-50
                newName.y = -50;
                // 绑定 touchstart触摸事件
                newName.on('touchstart', () => {
                    // 查询元素在数组中的索引值
                    Array.prototype.indexValue = function (arr) {
                        for (let i = 0; i < this.length; i++) {
                            if (this[i] === arr) {
                                return i
                            }
                        }
                    }
                    // 获取索引值
                    let shapeIndex = shapeArray.findIndex(v => newName === v);
                    // 从数组中删除
                    shapeArray.splice(shapeIndex, 1);
                    // 销毁
                    newName.destroy();
                    // 动态显示分数
                    that.animationOfScore();
                    innerAudioContext.play();
                    // 随机产生红包金额 最小到最大值之间的金额数
                    let changeOfScore = 0;
                    if (this.mode === 1) {
                        changeOfScore = parseFloat(this.packetArr[index])
                    } else {
                        changeOfScore = parseFloat(Math.random() * this.max + this.min)
                    }
                    // 当前总金额
                    let nowScore = that.score + changeOfScore
                    that.score = nowScore;
                    that.showScore = nowScore.toFixed(this.decimal);
                    that.showChangeScore = changeOfScore.toFixed(this.decimal);
                    that.$emit('scoreChange', changeOfScore.toFixed(this.decimal));
                })

                newStage.add(newName)
                //将创建的红包shape都放入数组中
                shapeArray.push(newName)
            },

            //分数动画
            animationOfScore() {
                let vm = this;
                const animation = uni.createAnimation({
                    duration: 300,
                    timingFunction: 'ease'
                });
                vm.animation = animation;
                animation.opacity(1).step();
                TimeoutTimers.push(setTimeout(() => {
                    animation.opacity(0).step();
                    vm.animationData = animation.export();
                }, 10));
            },
            // 红包下落
            packetMoveDown(bgStage) {
                let that = this;
                that.packetMoveDownTimer = setInterval(function () {
                    shapeArray.forEach(function (value, i) {
                        value.y = value.y + 3
                        if (value.y > info.windowHeight) {
                            bgStage.remove(value)
                            shapeArray.splice(i, 1)
                        }
                    });
                    bgStage.update()
                }, 10);
                IntervalTimers.push(that.packetMoveDownTimer);
            },
            // 开启一个倒计时关闭下红包雨
            stopRain(bgStage) {
                let that = this;
                // 不停地调用函数，直到 clearInterval()
                that.gameTimer = setInterval(function () {
                    let nowTime = that.time - 1;
                    // 时间为0的时候结束
                    if (nowTime <= 0) {
                        that.rainOver(bgStage)
                    }
                    that.time = nowTime;
                    that.$emit('timeChange', nowTime);
                }, 1000);
                IntervalTimers.push(this.gameTimer);
            },
            //关闭下红包雨（rainOver）
            rainOver(bgStage) {
                // 结束后清除定时器
                this.clearTimer();
                shapeArray.forEach(function (value, i) {
                    value.destroy();
                    bgStage.update();
                });
                this.isGameOver = true
            },
            // 点击我知道了
            handleFinish(e) {
                this.$emit('finish', e)
            },
            // 查看规则
            handleCheckrule(e) {
                this.$emit('checkrule', e)
            },
            // 打乱
            shuffle_pick(arr) {
                const arr2 = []
                for (let len = arr.length; len > 0;) {
                    let rnd = Math.floor(Math.random() * len)
                    arr2.push(arr[rnd])
                    arr[rnd] = arr[--len]
                }
                return arr2
            },
            // 生成红包
            randomRedPacketGenerator(num, total, min, max) {
                if (min * num > total || max * num < total) {
                    throw Error(`没法满足最最少 ${min} 最大 ${max} 的条件`)
                }
                let rnds = [], randNum, _max, _min
                for (let i = num; i >= 1; i--) {
                    _min = total - max * (i - 1) > min ? total - max * (i - 1) : min
                    _max = total - min * (i - 1) < max ? total - min * (i - 1) : max
                    randNum = parseFloat(Math.random() * (_max - _min) + _min).toFixed(this.decimal)
                    total = parseFloat(total - randNum)
                    rnds.push(randNum)
                }
                let result = []
                result = this.shuffle_pick(rnds)
                return result
            }
        }
    }
</script>

<style scoped lang="scss">
    $z-index-scale: 0.09;
    @function nFloor($n) {
        @return floor($n * $z-index-scale);
    }

    .ready-time {
        position: fixed;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        background-color: #000000;
        opacity: 0.8;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: flex-start;
        z-index: nFloor(10000);

        .top {
            margin-top: 244*1upx;
            font-size: 60*1upx;
            color: #fffdc5;
        }

        .countdown {
            margin-top: 100*1upx;
            font-size: 240*1upx;
            color: #fffdc5;
        }
    }

    .rain-bg {
        position: fixed;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: nFloor(9999);

        &.rain-bg-hide {
            display: none;
        }

        .cax-class {
            display: flex;
            position: fixed;
            flex-direction: column;
            justify-content: space-between;
            align-items: flex-end;
            width: 100%;
            height: 100%;
            /*background: url('https://tweapp.top1buyer.com/redBacketBG.jpg');*/
            background-size: 150% auto;

            text:nth-child(1) {
                position: absolute;
                text-align: center;
                font-size: 45*1upx;
                color: white;
                padding-left: 50*1upx;
                top: 150*1upx;
                font-weight: bold;
                left: 20*1upx;
                z-index: nFloor(1010);
            }

            .timeout-warpper {
                position: absolute;
                left: 50*1upx;
                top: 50*1upx;
                border: 4*1upx solid #fff;
                background: linear-gradient(to right, #6c87ee, #8a50b6);
                width: 180*1upx;
                height: 50*1upx;
                border-radius: 50*1upx;
                display: flex;
                flex-direction: row;
                align-items: center;
                justify-content: center;

                .timeout {
                    font-size: 28*1upx;
                    color: white;
                    text-align: center;
                }

                .sec {
                    display: flex;
                    flex-direction: row;
                    align-items: center;
                    justify-content: center;

                    .numOfTime {
                        font-size: 40*1upx;
                        font-weight: bold;
                        color: white;
                    }

                    .miao {
                        font-size: 40*1upx;
                        font-weight: bold;
                        color: white;
                    }
                }
            }

            .rain-score {
                position: absolute;
                font-size: 45*1upx;
                color: white;
                padding-left: 50*1upx;
                top: 150*1upx;
                font-weight: bold;
                left: 20*1upx;
                z-index: nFloor(1010);
                display: flex;
                flex-direction: row;
                align-items: baseline;

                .scoreChangeClass {
                    margin-left: 10*1upx;
                    font-size: 40*1upx;
                    color: #fffdc5;
                    opacity: 0;
                }

            }
        }
    }

    .rain-over {
        background: #000000;
        position: fixed;

        .bg {
            display: flex;
            margin: 40*1upx auto;
            text-align: center;
            background: url("https://tweapp.top1buyer.com/l-rain-bg@2x.png") no-repeat;
            background-size: cover;
            width: 750*1upx;
            height: 1000*1upx;

            .shadeView {
                margin: 176*1upx auto;
                text-align: center;
                background: url("https://tweapp.top1buyer.com/l-rain-gold@2x.png") no-repeat;
                background-size: cover;
                display: flex;
                flex-direction: column;
                justify-content: center;
                width: 550*1upx;
                height: 700*1upx;
                align-items: center;
                z-index: nFloor(9999);

                .shadeView-top {
                    margin-top: 30*1upx;
                    font-size: 40*1upx;
                    color: #ffffff;
                }

                .shadeView_scoreView {
                    width: 360*1upx;
                    height: 220*1upx;
                    line-height: 220*1upx;
                    background-size: 100% 100%;
                    margin-top: 70*1upx;
                    display: flex;
                    flex-direction: row;
                    justify-content: center;
                    align-items: baseline;

                    /* box-sizing:border-box; */

                    text:nth-child(1) {
                        font-size: 100*1upx;
                        color: #ffffff;
                        line-height: 76*1upx;
                    }

                    text:nth-child(2) {
                        font-size: 30*1upx;
                        color: #ffffff;
                        margin-left: 12*1upx;
                    }
                }

                .shadeView_gameOverBtn {
                    width: 550*1upx;
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    justify-content: center;

                    .explain {
                        font-size: 30*1upx;
                        color: #ffffff;
                    }

                    .btn {
                        margin-top: 58*1upx;
                        width: 300*1upx;
                        height: 70*1upx;
                        background-color: #fff9e8;
                        text-align: center;
                        line-height: 70*1upx;
                        border-radius: 40*1upx;
                        font-size: 30*1upx;
                        color: #b10000;
                    }

                    .rule {
                        margin-top: 28*1upx;
                        font-size: 24*1upx;
                        color: #ffffff;
                        text-decoration: underline;
                    }
                }

            }

        }
    }

</style>
<style lang="less">
    .azm-index-components {
    }
</style>
